<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    //订阅
    class Dep{
        constructor(){
            this.subs=[]
        }
        depend(){
            this.subs.push(Dep.target)
        }
        notify(){
            this.subs.forEach(wat=>{
                wat.updata();
            })
        }
    }
    // 观察者
    class Watcher{
        constructor(data,key){
            this.value=data;
            this.key=key;
            Dep.target=this
            this.get()
            Dep.target=null
        }
        // 观察者的响应动作，更新页面模板
        updata(){
            console.log('监听'+this.key+'的water触发了 ，新的值='+this.get())
        }
        get(){
            return this.value[this.key]
        }
    }


    function defineReacrive(obj,key){
        let value=obj[key]
        let dep=new Dep()
        Object.defineProperty(obj,key,{
            get(){
                console.log('正在访问'+key)
                // 有一个观察者正在观察数据
                if(Dep.target){
                    dep.depend()
                }
                return value
            },

            set(newvalue){
                console.log('正在修改'+key)
                value=newvalue
                dep.notify();
            }
        })

    }
    class Observer{
        constructor(obj){
            this.value=obj
            if(Array.isArray(obj)){
                console.log('我是数组')
            }else{
                console.log('我是对象')
                this.walk()
            }
        }
        walk(){
            Object.keys(this.value).forEach(key=>{
                // 做拦截
                defineReacrive(this.value,key)
            })
        }
    }

    function obsever(value){
        // 不是对象就返回
        if(typeof value !='object') return ;
        

        new Observer(value)
        
    }


    function Vue(obj){
        Object.keys(obj).forEach(key=>{
            this[key]=obj[key]
        });
        obsever(obj.data)
        // console.log(this)
        new Watcher(this.data,'count')
        new Watcher(this.data,'num')

    }
    const vm=new Vue({
        data:{
            count:0,
            num:1
        }
    })
    console.log(vm)
    vm.data.num++
</script>
</html>